package com.kevin.epacms.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.kevin.epacms.constant.CommonConstant;
import com.kevin.epacms.service.MailService;
import com.kevin.epacms.service.UserService;
import com.kevin.epacms.util.RedisUtil;
import com.kevin.epacms.util.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.mail.MailProperties;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author kevin
 * @since 2022/11/11 21:26
 */
@Slf4j
@Service
public class MailServiceImpl implements MailService {
    @Resource
    private MailProperties mailProperties;
    @Resource
    private UserService userService;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    JavaMailSender javaMailSender;


    @Override
    public Result isExistEmail(String email) {
        boolean exist = userService.isExistEmail(email);
        return exist ? Result.fail("该邮箱已被注册") : Result.ok("该邮箱未被注册");
    }

    @Override
    public Result getCode(String email) {
        long time = 5L;
        String key = CommonConstant.EMAIL_PREFIX + email;
        String code = redisUtil.get(key);
        if (StrUtil.isNotBlank(code)) {
            Long expire = redisUtil.getExpire(key, TimeUnit.SECONDS);
            // 发送验证码后的一分钟内不能再发
            if (Objects.nonNull(expire) && expire >= (time - 1L) * 60) {
                return Result.fail("请求太频繁，请稍后再试");
            }
            redisUtil.deleteKey(key);
        }
        // 重新生成验证码
        code = RandomUtil.randomNumbers(6);
        boolean isSend = sendMail(email, code);
        if (!isSend){
            log.warn("向{}邮箱，发送验证码{}失败", email, code);
            return Result.fail(CommonConstant.FAIL);
        }
        redisUtil.set(key, code, time, TimeUnit.MINUTES);
        log.info("向{}邮箱，发送验证码{}成功", email, code);
        return Result.ok(CommonConstant.SUCCESS);
    }

    @Override
    public Result noticeEmail(String email) {
        if (StrUtil.isBlank(email)) {
            return Result.fail("邮箱不能为空");
        }
        String subject = "同学，请及时打卡 O(∩_∩)O";
        String text = "请坚持每天打卡";
        SimpleMailMessage mailMessage = emailBasicInfo(subject, text, email);
        try {
            javaMailSender.send(mailMessage);
            log.info("邮件发送成功 =====> " + mailMessage);
            return Result.ok("邮箱发送成功");
        } catch (MailException e) {
            log.error("邮件发送异常", e);
            return Result.fail("邮件发送异常");
        }
    }

    /**
     * 发送邮件
     *
     * @param email 电子邮件
     * @param code  验证码
     * @return boolean
     */
    private boolean sendMail(String email, String code) {
        //判断邮箱是否为空
        if(StrUtil.isBlank(email)){
            return false;
        }
        String subject = "邮箱验证码";
        String text = "验证码为：" + code + ", 有效时间为5分钟";
        SimpleMailMessage mailMessage = emailBasicInfo(subject, text, email);
        try {
            javaMailSender.send(mailMessage);
            log.info("mailMessage =====> " + mailMessage);
            return true;
        } catch (MailException e) {
            log.error("发送邮箱异常", e);
            return false;
        }
    }

    /** 邮箱基本信息
     * @param subject 主题
     * @param text 正文
     * @param email 邮箱
     * @return SimpleMailMessage
     */
    private SimpleMailMessage emailBasicInfo(String subject, String text, String email){
        SimpleMailMessage mailMessage = new SimpleMailMessage();
        mailMessage.setFrom(mailProperties.getUsername());
        mailMessage.setTo(email);
        mailMessage.setSubject(subject);
        mailMessage.setText(text);
        mailMessage.setSentDate(new Date());
        return mailMessage;
    }
}
